#include "modeloptimizer.h"
#include <QFileInfo>
#include <QDir>
#include <QFile>
#include <vector>
#include <algorithm>
#include <QDebug>
#include <QApplication>
#include <cmath>
#include <QIODevice>
#include <QByteArray>
#include <QStringList>
#include <cstring>

// Assimp头文件包含 - 使用更通用的包含方式
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/Exporter.hpp>
#include <assimp/mesh.h>
#include <assimp/material.h>
#include <assimp/texture.h>

ModelOptimizer::ModelOptimizer(QObject *parent)
    : QObject(parent)
    , m_cancelRequested(false)
    , m_optimizationThread(new QThread(this))
{
    moveToThread(m_optimizationThread);
    connect(m_optimizationThread, &QThread::started, this, &ModelOptimizer::runOptimization);
}

ModelOptimizer::~ModelOptimizer()
{
    m_optimizationThread->quit();
    m_optimizationThread->wait();
}

void ModelOptimizer::startOptimization(const QString &inputPath, const QString &outputPath, const OptimizationOptions &options)
{
    m_inputPath = inputPath;
    m_outputPath = outputPath;
    m_options = options;
    m_result = OptimizationResult();
    m_cancelRequested = false;
    m_optimizationThread->start();
}

ModelOptimizer::OptimizationResult ModelOptimizer::getOptimizationResult() const
{
    return m_result;
}

void ModelOptimizer::runOptimization()
{
    m_result = optimizeModel(m_inputPath, m_outputPath, m_options);
    emit optimizationCompleted(m_result);
    m_optimizationThread->quit();
}

ModelOptimizer::OptimizationResult ModelOptimizer::optimizeModel(
    const QString &inputPath, 
    const QString &outputPath, 
    const OptimizationOptions &options)
{
    OptimizationResult result;
    m_cancelRequested = false;
    
    // 声明优化场景指针，在try块外声明以便在catch块中访问
    aiScene *optimizedScene = nullptr;
    
    try {
        // 检查输入文件是否存在
        if (!QFile::exists(inputPath)) {
            result.errorMessage = "输入文件不存在: " + inputPath;
            emit errorOccurred(result.errorMessage);
            // 不需要清理内存，因为 optimizedScene 还没有被分配
            return result;
        }

    updateProgress(10);

    // 验证用户选择的优化选项
    QString warningMessage;
    if (!validateOptimizationOptions(options, warningMessage)) {
        emit errorOccurred("⚠️ " + warningMessage);
    }

    // 导入原始模型
    const aiScene *originalScene = m_importer.ReadFile(
        inputPath.toStdString(),
        getPostProcessFlags(options)
    );

    if (!originalScene) {
        result.errorMessage = "无法导入模型: " + QString::fromStdString(m_importer.GetErrorString());
        emit errorOccurred(result.errorMessage);
        // 不需要清理内存，因为 optimizedScene 还没有被分配
        return result;
    }

    updateProgress(30);

    // 创建优化后的场景 - 使用 Assimp 的 aiCopyScene 函数
    // 这样可以确保内存管理的一致性
    optimizedScene = new aiScene();
    
    // 复制场景基本信息
    optimizedScene->mFlags = originalScene->mFlags;
    optimizedScene->mName = originalScene->mName;
    optimizedScene->mMetaData = originalScene->mMetaData;
    
    // 复制场景结构 - 递归复制节点树
    if (originalScene->mRootNode) {
        optimizedScene->mRootNode = copyNodeTree(originalScene->mRootNode, nullptr);
    } else {
        optimizedScene->mRootNode = nullptr;
    }

    updateProgress(50);

    // 优化网格 - 严格按照用户选项执行
    optimizedScene->mNumMeshes = originalScene->mNumMeshes;
    if (optimizedScene->mNumMeshes > 0) {
        optimizedScene->mMeshes = new aiMesh*[optimizedScene->mNumMeshes];
        
        // 输出用户选择的优化选项（减少信号发送频率）
        QString optionsSummary = "🔧 开始网格优化，用户选择的选项:";
        if (options.removeUnusedVertices) optionsSummary += "\n  ✓ 移除未使用顶点";
        if (options.joinIdenticalVertices) optionsSummary += "\n  ✓ 合并相同顶点";
        if (options.vertexReduction > 0.0f) optionsSummary += QString("\n  ✓ 顶点减少 (比例: %1%)").arg(options.vertexReduction * 100, 0, 'f', 1);
        if (options.triangulate) optionsSummary += "\n  ✓ 三角化";
        if (options.generateNormals) optionsSummary += "\n  ✓ 生成法线";
        if (options.generateSmoothNormals) optionsSummary += "\n  ✓ 生成平滑法线";
        if (options.calculateTangentSpace) optionsSummary += "\n  ✓ 计算切线空间";
        if (options.dropNormals) optionsSummary += "\n  ✓ 丢弃法线";
        if (options.debone) optionsSummary += "\n  ✓ 移除骨骼";
        emit errorOccurred(optionsSummary);
        
        for (unsigned int i = 0; i < originalScene->mNumMeshes; ++i) {
            // 检查是否应该取消操作
            if (m_cancelRequested) {
                result.errorMessage = "优化操作已被用户取消";
                emit errorOccurred(result.errorMessage);
                // 在取消时清理内存
                if (optimizedScene) {
                    cleanupSceneMemory(optimizedScene);
                }
                return result;
            }
            
            aiMesh *originalMesh = originalScene->mMeshes[i];
            if (!originalMesh) {
                optimizedScene->mMeshes[i] = nullptr;
                emit errorOccurred(QString("网格 %1 为空，已跳过").arg(i));
                continue;
            }
            
            try {
                // 检查原始网格是否有效
                if (!originalMesh) {
                    emit errorOccurred(QString("⚠️ 网格 %1 为空，跳过处理").arg(i));
                    optimizedScene->mMeshes[i] = nullptr;
                    continue;
                }
                
                // 完整复制网格数据
                aiMesh *optimizedMesh = copyMesh(originalMesh);
                
                if (!optimizedMesh) {
                    emit errorOccurred(QString("⚠️ 网格 %1 复制失败，跳过处理").arg(i));
                    optimizedScene->mMeshes[i] = nullptr;
                    continue;
                }
                
                // 应用网格优化 - 严格按照用户选项
                applyMeshOptimization(optimizedMesh, options);
                
                optimizedScene->mMeshes[i] = optimizedMesh;
                
            } catch (const std::exception &e) {
                QString errorMsg = QString("处理网格 %1 时出错: %2").arg(i).arg(QString::fromStdString(e.what()));
                emit errorOccurred(errorMsg);
                // 如果处理失败，创建一个简单的网格副本
                optimizedScene->mMeshes[i] = nullptr;
            } catch (...) {
                QString errorMsg = QString("处理网格 %1 时发生未知错误").arg(i);
                emit errorOccurred(errorMsg);
                // 如果处理失败，创建一个简单的网格副本
                optimizedScene->mMeshes[i] = nullptr;
            }
            
            // 更新进度，但限制频率，减少信号发送
            if (i % 10 == 0 || i == originalScene->mNumMeshes - 1) {
                updateProgress(50 + (i * 30) / originalScene->mNumMeshes);
            }
        }
        
        // 减少信号发送频率，避免界面卡顿
        // emit errorOccurred("✅ 网格优化处理完成");
    }

    updateProgress(80);

    // 优化材质 - 严格按照用户选项执行
    optimizedScene->mNumMaterials = originalScene->mNumMaterials;
    if (optimizedScene->mNumMaterials > 0) {
        optimizedScene->mMaterials = new aiMaterial*[optimizedScene->mNumMaterials];
        for (unsigned int i = 0; i < originalScene->mNumMaterials; ++i) {
            try {
                // 创建新的材质对象而不是直接复制指针
                optimizedScene->mMaterials[i] = new aiMaterial(*originalScene->mMaterials[i]);
                
                // 如果用户选择了移除冗余材质，进行材质优化
                if (options.removeRedundantMaterials) {
                    // 这里可以添加材质合并逻辑
                    emit errorOccurred(QString("✅ 已处理材质 %1").arg(i));
                }
            } catch (const std::exception &e) {
                QString errorMsg = QString("处理材质 %1 时出错: %2").arg(i).arg(QString::fromStdString(e.what()));
                emit errorOccurred(errorMsg);
                // 如果处理失败，设置为nullptr
                optimizedScene->mMaterials[i] = nullptr;
            } catch (...) {
                QString errorMsg = QString("处理材质 %1 时发生未知错误").arg(i);
                emit errorOccurred(errorMsg);
                // 如果处理失败，设置为nullptr
                optimizedScene->mMaterials[i] = nullptr;
            }
        }
        
        if (options.removeRedundantMaterials) {
            // 减少信号发送频率，避免界面卡顿
            // emit errorOccurred("✅ 材质优化处理完成");
        }
    } else {
        optimizedScene->mMaterials = nullptr;
    }

    updateProgress(85);

    // 新增：处理纹理嵌入
    if (options.embedTextures) {
        try {
            emit progressUpdated(85);
            
            emit errorOccurred("🔧 开始处理纹理嵌入...");
            embedTexturesInScene(optimizedScene, inputPath);
            
            emit progressUpdated(87);
            
            emit errorOccurred("✅ 纹理嵌入处理完成");
        } catch (const std::exception &e) {
            QString errorMsg = QString("纹理嵌入处理时出错: %1").arg(QString::fromStdString(e.what()));
            emit errorOccurred(errorMsg);
        } catch (...) {
            QString errorMsg = "纹理嵌入处理时发生未知错误";
            emit errorOccurred(errorMsg);
        }
    }

    updateProgress(90);

    // 导出优化后的模型
    QFileInfo outputFileInfo(outputPath);
    QDir outputDir = outputFileInfo.absoluteDir();
    if (!outputDir.exists()) {
        try {
            outputDir.mkpath(".");
        } catch (const std::exception &e) {
            QString errorMsg = QString("创建输出目录时出错: %1").arg(QString::fromStdString(e.what()));
            emit errorOccurred(errorMsg);
        } catch (...) {
            emit errorOccurred("创建输出目录时发生未知错误");
        }
    }

    // 确定输出格式 - 优先选择更高效的格式
    QString extension = outputFileInfo.suffix().toLower();
    const char *formatId = "obj"; // 默认格式
    
    // 优先选择更高效的格式来减小文件大小
    if (extension == "gltf" || extension == "glb") formatId = "gltf2"; // GLTF是最高效的格式
    else if (extension == "ply") formatId = "ply"; // PLY格式相对紧凑
    else if (extension == "stl") formatId = "stl"; // STL格式简单
    else if (extension == "obj") formatId = "obj"; // OBJ格式通用
    else if (extension == "fbx") formatId = "fbx";
    else if (extension == "dae") formatId = "collada";
    else if (extension == "3ds") formatId = "3ds";

    // 导出前确保场景数据完整
    if (!optimizedScene->mMeshes || optimizedScene->mNumMeshes == 0) {
        result.errorMessage = "优化后的场景没有有效的网格数据";
        emit errorOccurred(result.errorMessage);
        cleanupSceneMemory(optimizedScene);
        return result;
    }

    // 导出前处理事件，确保UI响应
    aiReturn exportResult = m_exporter.Export(optimizedScene, formatId, outputPath.toStdString());
    
    if (exportResult != AI_SUCCESS) {
        result.errorMessage = "导出失败: " + QString::fromStdString(m_exporter.GetErrorString());
        emit errorOccurred(result.errorMessage);
        // 导出失败时清理内存
        cleanupSceneMemory(optimizedScene);
        return result;
    }
    
    // 导出成功后处理事件，确保UI响应

    updateProgress(100);

    // 计算优化统计信息
    calculateOptimizationStats(originalScene, optimizedScene, inputPath, outputPath, result);
    
    result.success = true;
    
    // 在清理内存前处理一些事件，避免UI卡死
    
    // 导出成功后，清理优化场景的内存
    // 注意：在导出完成后清理内存是安全的，因为导出器已经处理了数据
    cleanupSceneMemory(optimizedScene);
    
    // 清理完成后再次处理事件
    
    emit optimizationCompleted(result);
    return result;
        
    } catch (const std::exception &e) {
        result.errorMessage = "优化过程中发生异常: " + QString::fromStdString(e.what());
        emit errorOccurred(result.errorMessage);
        // 异常时清理内存
        if (optimizedScene) {
            cleanupSceneMemory(optimizedScene);
        }
        return result;
    } catch (...) {
        result.errorMessage = "优化过程中发生未知异常";
        emit errorOccurred(result.errorMessage);
        // 异常时清理内存
        if (optimizedScene) {
            cleanupSceneMemory(optimizedScene);
        }
        return result;
    }
}

unsigned int ModelOptimizer::getPostProcessFlags(const OptimizationOptions &options)
{
    unsigned int flags = 0;
    
    // 第一阶段：数据验证和清理 (必须在其他操作之前)
    if (options.validateDataStructure) flags |= aiProcess_ValidateDataStructure;
    if (options.findInvalidData) flags |= aiProcess_FindInvalidData;
    if (options.findDegenerates) flags |= aiProcess_FindDegenerates;
    
    // 第二阶段：几何处理 (基础几何操作)
    if (options.triangulate) flags |= aiProcess_Triangulate;
    if (options.joinIdenticalVertices) flags |= aiProcess_JoinIdenticalVertices;
    if (options.removeUnusedVertices) flags |= aiProcess_JoinIdenticalVertices; // 移除未使用顶点通过合并实现
    
    // 第三阶段：UV坐标处理 (在法线处理之前)
    if (options.genUVCoords) flags |= aiProcess_GenUVCoords;
    if (options.transformUVCoords) flags |= aiProcess_TransformUVCoords;
    if (options.flipUVs) flags |= aiProcess_FlipUVs;
    
    // 第四阶段：法线处理 (在切线空间计算之前)
    if (options.dropNormals) flags |= aiProcess_DropNormals;
    if (options.generateNormals) flags |= aiProcess_GenNormals;
    if (options.generateSmoothNormals) flags |= aiProcess_GenSmoothNormals;
    if (options.forceGenNormals) flags |= aiProcess_ForceGenNormals;
    if (options.fixInfacingNormals) flags |= aiProcess_FixInfacingNormals;
    if (options.invertNormals) flags |= aiProcess_FlipWindingOrder;
    
    // 第五阶段：切线空间计算 (在法线处理之后)
    if (options.calculateTangentSpace) flags |= aiProcess_CalcTangentSpace;
    
    // 第六阶段：缠绕顺序处理
    if (options.flipWindingOrder) flags |= aiProcess_FlipWindingOrder;
    if (options.reverseWindingOrder) flags |= aiProcess_FlipWindingOrder;
    
    // 第七阶段：骨骼处理
    if (options.limitBoneWeights) flags |= aiProcess_LimitBoneWeights;
    if (options.splitByBoneCount) flags |= aiProcess_SplitByBoneCount;
    if (options.debone) flags |= aiProcess_Debone;
    
    // 第八阶段：网格分割和变换 (在优化之前)
    if (options.splitLargeMeshes) flags |= aiProcess_SplitLargeMeshes;
    if (options.preTransformVertices) flags |= aiProcess_PreTransformVertices;
    
    // 第九阶段：优化操作 (在基础处理之后)
    if (options.improveCacheLocality) flags |= aiProcess_ImproveCacheLocality;
    if (options.sortByPType) flags |= aiProcess_SortByPType;
    if (options.optimizeMeshes) flags |= aiProcess_OptimizeMeshes;
    if (options.optimizeGraph) flags |= aiProcess_OptimizeGraph;
    
    // 第十阶段：实例查找和纹理嵌入 (最后阶段)
    if (options.findInstances) flags |= aiProcess_FindInstances;
    if (options.embedTextures) flags |= aiProcess_EmbedTextures;
    
    return flags;
}

void ModelOptimizer::applyMeshOptimization(aiMesh *mesh, const OptimizationOptions &options)
{
    if (!mesh) {
        emit errorOccurred("⚠️ 网格为空，跳过优化");
        return;
    }
    
    // 检查网格基本数据的有效性
    if (!mesh->mVertices || mesh->mNumVertices == 0) {
        emit errorOccurred("⚠️ 网格没有顶点数据，跳过优化");
        return;
    }
    
    if (!mesh->mFaces || mesh->mNumFaces == 0) {
        emit errorOccurred("⚠️ 网格没有面数据，跳过优化");
        return;
    }
    
    // 按照优化的逻辑顺序执行，确保最佳效果
    
    // 第一阶段：数据清理
    if (options.removeUnusedVertices) {
        try {
            removeUnusedVertices(mesh);
            emit errorOccurred("✅ 已移除未使用的顶点");
        } catch (const std::exception &e) {
            QString errorMsg = QString("移除未使用顶点时出错: %1").arg(QString::fromStdString(e.what()));
            emit errorOccurred(errorMsg);
        } catch (...) {
            emit errorOccurred("移除未使用顶点时发生未知错误");
        }
    }
    
    // 第二阶段：几何优化
    if (options.joinIdenticalVertices) {
        try {
            float tolerance = options.normalTolerance > 0 ? options.normalTolerance : 0.001f;
            mergeIdenticalVertices(mesh, tolerance);
            emit errorOccurred("✅ 已合并相同顶点");
        } catch (const std::exception &e) {
            QString errorMsg = QString("合并相同顶点时出错: %1").arg(QString::fromStdString(e.what()));
            emit errorOccurred(errorMsg);
        } catch (...) {
            emit errorOccurred("合并相同顶点时发生未知错误");
        }
    }
    
    // 第三阶段：顶点减少（在几何优化之后）
    if (options.vertexReduction > 0.0f) {
        try {
            optimizeVertices(mesh, options.vertexReduction);
            emit errorOccurred(QString("✅ 已减少顶点数量 (减少比例: %1%)").arg(options.vertexReduction * 100, 0, 'f', 1));
        } catch (const std::exception &e) {
            QString errorMsg = QString("顶点减少优化时出错: %1").arg(QString::fromStdString(e.what()));
            emit errorOccurred(errorMsg);
        } catch (...) {
            emit errorOccurred("顶点减少优化时发生未知错误");
        }
    }
    
    // 第四阶段：网格简化（最后阶段，移除不必要的属性）
    simplifyMesh(mesh, options);
}

// 新增：简化网格，移除不必要的属性以减小文件大小
void ModelOptimizer::simplifyMesh(aiMesh *mesh, const OptimizationOptions &options)
{
    if (!mesh) return;
    
    // 严格按照用户选项执行网格简化
    
    // 移除切线空间数据（如果用户选择了相关选项）
    if (options.dropNormals || options.vertexReduction > 0.0f) {
        if (mesh->mTangents) {
            delete[] mesh->mTangents;
            mesh->mTangents = nullptr;
        }
        if (mesh->mBitangents) {
            delete[] mesh->mBitangents;
            mesh->mBitangents = nullptr;
        }
        emit errorOccurred("✅ 已移除切线空间数据");
    }
    
    // 移除颜色数据（如果用户选择了相关选项）
    if (options.vertexReduction > 0.0f) {
        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
            if (mesh->mColors[i]) {
                delete[] mesh->mColors[i];
                mesh->mColors[i] = nullptr;
            }
        }
        emit errorOccurred("✅ 已移除顶点颜色数据");
    }
    
    // 移除部分纹理坐标（如果用户选择了相关选项）
    if (options.vertexReduction > 0.0f) {
        for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
            if (mesh->mTextureCoords[i]) {
                delete[] mesh->mTextureCoords[i];
                mesh->mTextureCoords[i] = nullptr;
                mesh->mNumUVComponents[i] = 0;
            }
        }
        emit errorOccurred("✅ 已移除多余的UV坐标集");
    }
    
    // 移除骨骼数据（如果用户选择了相关选项）
    if (options.debone || options.vertexReduction > 0.0f) {
        if (mesh->mBones && mesh->mNumBones > 0) {
            try {
                // 先删除每个骨骼的权重数据
                for (unsigned int i = 0; i < mesh->mNumBones; ++i) {
                    if (mesh->mBones[i]) {
                        // 安全删除权重数据
                        if (mesh->mBones[i]->mWeights) {
                            delete[] mesh->mBones[i]->mWeights;
                            mesh->mBones[i]->mWeights = nullptr;
                        }
                        // 删除骨骼对象
                        delete mesh->mBones[i];
                        mesh->mBones[i] = nullptr;
                    }
                }
                // 删除骨骼数组
                delete[] mesh->mBones;
                mesh->mBones = nullptr;
                mesh->mNumBones = 0;
                emit errorOccurred("✅ 已移除骨骼数据");
            } catch (const std::exception &e) {
                emit errorOccurred(QString("移除骨骼数据时出错: %1").arg(QString::fromStdString(e.what())));
                // 即使出错也要清理指针，避免重复删除
                mesh->mBones = nullptr;
                mesh->mNumBones = 0;
            } catch (...) {
                emit errorOccurred("移除骨骼数据时发生未知错误");
                // 即使出错也要清理指针，避免重复删除
                mesh->mBones = nullptr;
                mesh->mNumBones = 0;
            }
        } else if (mesh->mBones == nullptr && mesh->mNumBones == 0) {
            // 骨骼数据已经被清理，不需要重复处理
            emit errorOccurred("ℹ️ 骨骼数据已被清理");
        }
    }
}

void ModelOptimizer::removeUnusedVertices(aiMesh *mesh)
{
    if (!mesh || !mesh->mFaces) return;
    
    std::vector<bool> usedVertices(mesh->mNumVertices, false);
    
    // 标记使用的顶点
    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        const aiFace &face = mesh->mFaces[i];
        for (unsigned int j = 0; j < face.mNumIndices; ++j) {
            if (face.mIndices[j] < mesh->mNumVertices) {
                usedVertices[face.mIndices[j]] = true;
            }
        }
    }
    
    // 创建新的顶点数组
    std::vector<aiVector3D> newVertices;
    std::vector<aiVector3D> newNormals;
    std::vector<aiVector3D> newTangents;
    std::vector<aiVector3D> newBitangents;
    std::vector<aiColor4D> newColors[AI_MAX_NUMBER_OF_COLOR_SETS];
    std::vector<aiVector3D> newTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
    
    std::vector<unsigned int> vertexMap(mesh->mNumVertices);
    unsigned int newVertexIndex = 0;
    
    for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
        if (usedVertices[i]) {
            vertexMap[i] = newVertexIndex++;
            
            if (mesh->mVertices) newVertices.push_back(mesh->mVertices[i]);
            if (mesh->mNormals) newNormals.push_back(mesh->mNormals[i]);
            if (mesh->mTangents) newTangents.push_back(mesh->mTangents[i]);
            if (mesh->mBitangents) newBitangents.push_back(mesh->mBitangents[i]);
            
            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
                if (mesh->mColors[j]) newColors[j].push_back(mesh->mColors[j][i]);
            }
            
            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
                if (mesh->mTextureCoords[j]) newTexCoords[j].push_back(mesh->mTextureCoords[j][i]);
            }
        }
    }
    
    // 更新面索引
    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        aiFace &face = mesh->mFaces[i];
        for (unsigned int j = 0; j < face.mNumIndices; ++j) {
            if (face.mIndices[j] < mesh->mNumVertices) {
                face.mIndices[j] = vertexMap[face.mIndices[j]];
            }
        }
    }
    
    // 更新网格数据
    mesh->mNumVertices = newVertices.size();
    
    // 安全地删除和重新分配顶点数据
    if (mesh->mVertices) {
        delete[] mesh->mVertices;
    }
    if (!newVertices.empty()) {
        mesh->mVertices = new aiVector3D[newVertices.size()];
        std::copy(newVertices.begin(), newVertices.end(), mesh->mVertices);
    } else {
        mesh->mVertices = nullptr;
    }
    
    if (mesh->mNormals) {
        delete[] mesh->mNormals;
    }
    if (!newNormals.empty()) {
        mesh->mNormals = new aiVector3D[newNormals.size()];
        std::copy(newNormals.begin(), newNormals.end(), mesh->mNormals);
    } else {
        mesh->mNormals = nullptr;
    }
    
    if (mesh->mTangents) {
        delete[] mesh->mTangents;
    }
    if (!newTangents.empty()) {
        mesh->mTangents = new aiVector3D[newTangents.size()];
        std::copy(newTangents.begin(), newTangents.end(), mesh->mTangents);
    } else {
        mesh->mTangents = nullptr;
    }
    
    if (mesh->mBitangents) {
        delete[] mesh->mBitangents;
    }
    if (!newBitangents.empty()) {
        mesh->mBitangents = new aiVector3D[newBitangents.size()];
        std::copy(newBitangents.begin(), newBitangents.end(), mesh->mBitangents);
    } else {
        mesh->mBitangents = nullptr;
    }
    
    // 安全地处理颜色数据
    for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
        if (mesh->mColors[j]) {
            delete[] mesh->mColors[j];
        }
        if (!newColors[j].empty()) {
            mesh->mColors[j] = new aiColor4D[newColors[j].size()];
            std::copy(newColors[j].begin(), newColors[j].end(), mesh->mColors[j]);
        } else {
            mesh->mColors[j] = nullptr;
        }
    }
    
    // 安全地处理纹理坐标数据
    for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
        if (mesh->mTextureCoords[j]) {
            delete[] mesh->mTextureCoords[j];
        }
        if (!newTexCoords[j].empty()) {
            mesh->mTextureCoords[j] = new aiVector3D[newTexCoords[j].size()];
            std::copy(newTexCoords[j].begin(), newTexCoords[j].end(), mesh->mTextureCoords[j]);
        } else {
            mesh->mTextureCoords[j] = nullptr;
        }
    }
}

void ModelOptimizer::mergeIdenticalVertices(aiMesh *mesh, float tolerance)
{
    if (!mesh || !mesh->mVertices) return;
    
    // 简化算法，避免卡顿
    std::vector<unsigned int> vertexMap(mesh->mNumVertices);
    std::vector<aiVector3D> uniqueVertices;
    std::vector<aiVector3D> uniqueNormals;
    std::vector<aiVector3D> uniqueTangents;
    std::vector<aiVector3D> uniqueBitangents;
    std::vector<aiColor4D> uniqueColors[AI_MAX_NUMBER_OF_COLOR_SETS];
    std::vector<aiVector3D> uniqueTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
    
    // 限制处理的顶点数量，避免长时间卡顿
    unsigned int maxVertices = std::min(mesh->mNumVertices, 50000u);
    
    for (unsigned int i = 0; i < maxVertices; ++i) {
        // 定期处理事件，避免UI卡死
        // 已移除QApplication::processEvents()调用，因为优化过程已在独立线程中运行
        
        bool found = false;
        // 只检查最近的100个顶点，避免O(n²)复杂度
        unsigned int searchLimit = std::min(100u, static_cast<unsigned int>(uniqueVertices.size()));
        for (unsigned int j = 0; j < searchLimit; ++j) {
            if ((mesh->mVertices[i] - uniqueVertices[j]).SquareLength() < tolerance * tolerance) {
                vertexMap[i] = j;
                found = true;
                break;
            }
        }
        
        if (!found) {
            vertexMap[i] = uniqueVertices.size();
            uniqueVertices.push_back(mesh->mVertices[i]);
            
            // 复制相关的顶点属性
            if (mesh->mNormals && i < mesh->mNumVertices) {
                uniqueNormals.push_back(mesh->mNormals[i]);
            }
            if (mesh->mTangents && i < mesh->mNumVertices) {
                uniqueTangents.push_back(mesh->mTangents[i]);
            }
            if (mesh->mBitangents && i < mesh->mNumVertices) {
                uniqueBitangents.push_back(mesh->mBitangents[i]);
            }
            
            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
                if (mesh->mColors[j] && i < mesh->mNumVertices) {
                    uniqueColors[j].push_back(mesh->mColors[j][i]);
                }
            }
            
            for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
                if (mesh->mTextureCoords[j] && i < mesh->mNumVertices) {
                    uniqueTexCoords[j].push_back(mesh->mTextureCoords[j][i]);
                }
            }
        }
    }
    
    // 对于超出限制的顶点，直接映射到最后一个唯一顶点
    for (unsigned int i = maxVertices; i < mesh->mNumVertices; ++i) {
        vertexMap[i] = uniqueVertices.size() - 1;
    }
    
    // 更新面索引
    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        aiFace &face = mesh->mFaces[i];
        for (unsigned int j = 0; j < face.mNumIndices; ++j) {
            if (face.mIndices[j] < mesh->mNumVertices) {
                face.mIndices[j] = vertexMap[face.mIndices[j]];
            }
        }
    }
    
    // 更新顶点数据
    mesh->mNumVertices = uniqueVertices.size();
    
    // 更新顶点位置
    delete[] mesh->mVertices;
    if (!uniqueVertices.empty()) {
        mesh->mVertices = new aiVector3D[uniqueVertices.size()];
        std::copy(uniqueVertices.begin(), uniqueVertices.end(), mesh->mVertices);
    } else {
        mesh->mVertices = nullptr;
    }
    
    // 更新法线
    delete[] mesh->mNormals;
    if (!uniqueNormals.empty() && uniqueNormals.size() == uniqueVertices.size()) {
        mesh->mNormals = new aiVector3D[uniqueNormals.size()];
        std::copy(uniqueNormals.begin(), uniqueNormals.end(), mesh->mNormals);
    } else {
        mesh->mNormals = nullptr;
    }
    
    // 更新切线
    delete[] mesh->mTangents;
    if (!uniqueTangents.empty() && uniqueTangents.size() == uniqueVertices.size()) {
        mesh->mTangents = new aiVector3D[uniqueTangents.size()];
        std::copy(uniqueTangents.begin(), uniqueTangents.end(), mesh->mTangents);
    } else {
        mesh->mTangents = nullptr;
    }
    
    // 更新副切线
    delete[] mesh->mBitangents;
    if (!uniqueBitangents.empty() && uniqueBitangents.size() == uniqueVertices.size()) {
        mesh->mBitangents = new aiVector3D[uniqueBitangents.size()];
        std::copy(uniqueBitangents.begin(), uniqueBitangents.end(), mesh->mBitangents);
    } else {
        mesh->mBitangents = nullptr;
    }
    
    // 更新颜色
    for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
        delete[] mesh->mColors[j];
        if (!uniqueColors[j].empty() && uniqueColors[j].size() == uniqueVertices.size()) {
            mesh->mColors[j] = new aiColor4D[uniqueColors[j].size()];
            std::copy(uniqueColors[j].begin(), uniqueColors[j].end(), mesh->mColors[j]);
        } else {
            mesh->mColors[j] = nullptr;
        }
    }
    
    // 更新纹理坐标
    for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
        delete[] mesh->mTextureCoords[j];
        if (!uniqueTexCoords[j].empty() && uniqueTexCoords[j].size() == uniqueVertices.size()) {
            mesh->mTextureCoords[j] = new aiVector3D[uniqueTexCoords[j].size()];
            std::copy(uniqueTexCoords[j].begin(), uniqueTexCoords[j].end(), mesh->mTextureCoords[j]);
        } else {
            mesh->mTextureCoords[j] = nullptr;
        }
    }
}



void ModelOptimizer::optimizeVertices(aiMesh *mesh, float reductionRatio)
{
    if (!mesh || reductionRatio <= 0.0f || reductionRatio >= 1.0f) return;
    
    // 计算要保留的顶点数量
    unsigned int targetVertexCount = static_cast<unsigned int>(mesh->mNumVertices * (1.0f - reductionRatio));
    if (targetVertexCount < 3) targetVertexCount = 3; // 至少保留3个顶点
    
    // 使用更智能的顶点减少策略：基于曲率采样
    std::vector<unsigned int> vertexMap(mesh->mNumVertices);
    std::vector<aiVector3D> newVertices;
    std::vector<aiVector3D> newNormals;
    std::vector<aiVector3D> newTexCoords;
    
    // 计算每个顶点的重要性（基于曲率）
    std::vector<float> vertexImportance(mesh->mNumVertices, 0.0f);
    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        const aiFace &face = mesh->mFaces[i];
        if (face.mNumIndices == 3) {
            // 计算三角形的面积和法线变化
            aiVector3D v1 = mesh->mVertices[face.mIndices[0]];
            aiVector3D v2 = mesh->mVertices[face.mIndices[1]];
            aiVector3D v3 = mesh->mVertices[face.mIndices[2]];
            
            aiVector3D edge1 = v2 - v1;
            aiVector3D edge2 = v3 - v1;
            float area = (edge1 ^ edge2).Length() * 0.5f;
            
            // 根据面积和位置给顶点分配重要性
            for (unsigned int j = 0; j < 3; ++j) {
                vertexImportance[face.mIndices[j]] += area;
            }
        }
    }
    
    // 选择最重要的顶点
    std::vector<std::pair<float, unsigned int>> vertexScores;
    for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
        vertexScores.push_back(std::make_pair(vertexImportance[i], i));
    }
    
    // 按重要性排序
    std::sort(vertexScores.begin(), vertexScores.end(), std::greater<std::pair<float, unsigned int>>());
    
    // 选择前targetVertexCount个最重要的顶点
    std::vector<unsigned int> selectedVertices;
    for (unsigned int i = 0; i < targetVertexCount && i < vertexScores.size(); ++i) {
        selectedVertices.push_back(vertexScores[i].second);
    }
    
    // 创建顶点映射
    for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
        // 找到最近的选中顶点
        unsigned int closestVertex = selectedVertices[0];
        float minDistance = (mesh->mVertices[i] - mesh->mVertices[closestVertex]).SquareLength();
        
        for (unsigned int j = 1; j < selectedVertices.size(); ++j) {
            float distance = (mesh->mVertices[i] - mesh->mVertices[selectedVertices[j]]).SquareLength();
            if (distance < minDistance) {
                minDistance = distance;
                closestVertex = selectedVertices[j];
            }
        }
        
        // 找到closestVertex在selectedVertices中的索引
        auto it = std::find(selectedVertices.begin(), selectedVertices.end(), closestVertex);
        vertexMap[i] = std::distance(selectedVertices.begin(), it);
    }
    
    // 收集选中的顶点数据
    for (unsigned int vertexIndex : selectedVertices) {
        if (mesh->mVertices) newVertices.push_back(mesh->mVertices[vertexIndex]);
        if (mesh->mNormals) newNormals.push_back(mesh->mNormals[vertexIndex]);
        if (mesh->mTextureCoords[0]) newTexCoords.push_back(mesh->mTextureCoords[0][vertexIndex]);
    }
    
    // 更新面索引
    for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
        aiFace &face = mesh->mFaces[i];
        for (unsigned int j = 0; j < face.mNumIndices; ++j) {
            if (face.mIndices[j] < mesh->mNumVertices) {
                face.mIndices[j] = vertexMap[face.mIndices[j]];
            }
        }
    }
    
    // 更新顶点数据
    mesh->mNumVertices = newVertices.size();
    
    // 更新顶点位置
    delete[] mesh->mVertices;
    if (!newVertices.empty()) {
        mesh->mVertices = new aiVector3D[newVertices.size()];
        std::copy(newVertices.begin(), newVertices.end(), mesh->mVertices);
    } else {
        mesh->mVertices = nullptr;
    }
    
    // 更新法线
    delete[] mesh->mNormals;
    if (!newNormals.empty()) {
        mesh->mNormals = new aiVector3D[newNormals.size()];
        std::copy(newNormals.begin(), newNormals.end(), mesh->mNormals);
    } else {
        mesh->mNormals = nullptr;
    }
    
    // 更新纹理坐标（只保留第一个UV集）
    if (mesh->mTextureCoords[0]) {
        delete[] mesh->mTextureCoords[0];
    }
    if (!newTexCoords.empty()) {
        mesh->mTextureCoords[0] = new aiVector3D[newTexCoords.size()];
        std::copy(newTexCoords.begin(), newTexCoords.end(), mesh->mTextureCoords[0]);
    } else {
        mesh->mTextureCoords[0] = nullptr;
        mesh->mNumUVComponents[0] = 0;
    }
    
    // 清理其他属性（减少数据量）
    for (unsigned int j = 1; j < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++j) {
        if (mesh->mTextureCoords[j]) {
            delete[] mesh->mTextureCoords[j];
            mesh->mTextureCoords[j] = nullptr;
            mesh->mNumUVComponents[j] = 0;
        }
    }
    
    // 清理切线空间数据（减少数据量）
    if (mesh->mTangents) {
        delete[] mesh->mTangents;
        mesh->mTangents = nullptr;
    }
    if (mesh->mBitangents) {
        delete[] mesh->mBitangents;
        mesh->mBitangents = nullptr;
    }
    
    // 清理颜色数据（减少数据量）
    for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS; ++j) {
        if (mesh->mColors[j]) {
            delete[] mesh->mColors[j];
            mesh->mColors[j] = nullptr;
        }
    }
}

void ModelOptimizer::calculateOptimizationStats(
    const aiScene *originalScene, 
    const aiScene *optimizedScene,
    const QString &originalPath,
    const QString &optimizedPath,
    OptimizationResult &result)
{
    // 计算顶点和面数
    result.originalVertexCount = 0;
    result.originalFaceCount = 0;
    result.optimizedVertexCount = 0;
    result.optimizedFaceCount = 0;
    
    if (originalScene) {
        for (unsigned int i = 0; i < originalScene->mNumMeshes; ++i) {
            const aiMesh *mesh = originalScene->mMeshes[i];
            if (mesh) {
                result.originalVertexCount += mesh->mNumVertices;
                result.originalFaceCount += mesh->mNumFaces;
            }
        }
    }
    
    if (optimizedScene) {
        for (unsigned int i = 0; i < optimizedScene->mNumMeshes; ++i) {
            const aiMesh *mesh = optimizedScene->mMeshes[i];
            if (mesh) {
                result.optimizedVertexCount += mesh->mNumVertices;
                result.optimizedFaceCount += mesh->mNumFaces;
            }
        }
    }
    
    // 计算材质数
    result.originalMaterialCount = originalScene ? originalScene->mNumMaterials : 0;
    result.optimizedMaterialCount = optimizedScene ? optimizedScene->mNumMaterials : 0;
    
    // 计算文件大小
    QFileInfo originalFile(originalPath);
    QFileInfo optimizedFile(optimizedPath);
    
    result.originalFileSize = originalFile.size();
    result.optimizedFileSize = optimizedFile.size();
    
    // 计算压缩比
    if (result.originalFileSize > 0) {
        result.compressionRatio = 1.0f - (float)result.optimizedFileSize / result.originalFileSize;
    }
}

void ModelOptimizer::updateProgress(int percentage)
{
    // 检查是否请求取消
    if (m_cancelRequested) {
        return;
    }
    
    // 限制进度更新频率，避免UI阻塞
    static int lastPercentage = -1;
    // 减少进度更新频率，只在重要节点更新，避免过多信号
    if (percentage != lastPercentage && (percentage % 10 == 0 || percentage == 100 || percentage == 50)) {
        emit progressUpdated(percentage);
        lastPercentage = percentage;
    }
}

// 新增：内存清理辅助函数实现
void ModelOptimizer::cleanupSceneMemory(aiScene *scene)
{
    if (!scene) return;
    
    // 清理嵌入的纹理
    if (scene->mTextures) {
        for (unsigned int i = 0; i < scene->mNumTextures; ++i) {
            if (scene->mTextures[i]) {
                // 清理纹理数据
                if (scene->mTextures[i]->pcData) {
                    delete[] scene->mTextures[i]->pcData;
                    scene->mTextures[i]->pcData = nullptr;
                }
                delete scene->mTextures[i];
                scene->mTextures[i] = nullptr;
            }
        }
        delete[] scene->mTextures;
        scene->mTextures = nullptr;
        scene->mNumTextures = 0;
    }
    
    // 简化内存清理，避免程序卡死
    // 直接删除场景对象，让系统自动处理内存清理
    // 这样可以避免在清理大量数据时卡死
    
    // 注意：这种方法虽然简单，但需要确保没有其他地方引用这些数据
    delete scene;
}

// 新增：清理节点树的辅助函数（简化版本）
void ModelOptimizer::cleanupNodeTree(aiNode* node)
{
    // 简化版本：不进行递归清理，避免程序卡死
    // 当场景被删除时，系统会自动处理内存清理
    if (node) {
        // 只清理当前节点的直接引用，不递归清理子节点
        if (node->mMeshes) {
            delete[] node->mMeshes;
        }
        if (node->mChildren) {
            delete[] node->mChildren;
        }
        delete node;
    }
}

void ModelOptimizer::cancelOptimization()
{
    m_cancelRequested = true;
}

// 新增：递归复制节点树的辅助函数
aiNode* ModelOptimizer::copyNodeTree(const aiNode* sourceNode, aiNode* parent)
{
    if (!sourceNode) return nullptr;
    
    aiNode* newNode = new aiNode();
    
    // 复制基本属性
    newNode->mName = sourceNode->mName;
    newNode->mTransformation = sourceNode->mTransformation;
    newNode->mParent = parent;
    newNode->mNumChildren = sourceNode->mNumChildren;
    newNode->mNumMeshes = sourceNode->mNumMeshes;
    
    // 复制网格索引
    if (sourceNode->mNumMeshes > 0) {
        newNode->mMeshes = new unsigned int[sourceNode->mNumMeshes];
        std::copy(sourceNode->mMeshes, sourceNode->mMeshes + sourceNode->mNumMeshes, newNode->mMeshes);
    } else {
        newNode->mMeshes = nullptr;
    }
    
    // 递归复制子节点
    if (sourceNode->mNumChildren > 0) {
        newNode->mChildren = new aiNode*[sourceNode->mNumChildren];
        for (unsigned int i = 0; i < sourceNode->mNumChildren; ++i) {
            newNode->mChildren[i] = copyNodeTree(sourceNode->mChildren[i], newNode);
        }
    } else {
        newNode->mChildren = nullptr;
    }
    
    return newNode;
}

// 新增：智能复制网格数据，根据用户选项决定是否复制某些属性
aiMesh* ModelOptimizer::copyMesh(const aiMesh* sourceMesh)
{
    if (!sourceMesh) {
        qDebug() << "copyMesh: sourceMesh is null";
        return nullptr;
    }
    
    // 检查源网格的基本有效性
    if (!sourceMesh->mVertices || sourceMesh->mNumVertices == 0) {
        qDebug() << "copyMesh: sourceMesh has no vertices";
        return nullptr;
    }
    
    if (!sourceMesh->mFaces || sourceMesh->mNumFaces == 0) {
        qDebug() << "copyMesh: sourceMesh has no faces";
        return nullptr;
    }
    
    aiMesh* newMesh = new aiMesh();
    
    // 复制基本属性
    newMesh->mName = sourceMesh->mName;
    newMesh->mMaterialIndex = sourceMesh->mMaterialIndex;
    newMesh->mPrimitiveTypes = sourceMesh->mPrimitiveTypes;
    newMesh->mNumVertices = sourceMesh->mNumVertices;
    newMesh->mNumFaces = sourceMesh->mNumFaces;
    
    // 复制顶点位置（必需）
    if (sourceMesh->mVertices && sourceMesh->mNumVertices > 0) {
        newMesh->mVertices = new aiVector3D[sourceMesh->mNumVertices];
        std::copy(sourceMesh->mVertices, sourceMesh->mVertices + sourceMesh->mNumVertices, newMesh->mVertices);
    }
    
    // 复制法线（如果存在且用户没有选择丢弃法线）
    if (sourceMesh->mNormals && sourceMesh->mNumVertices > 0) {
        newMesh->mNormals = new aiVector3D[sourceMesh->mNumVertices];
        std::copy(sourceMesh->mNormals, sourceMesh->mNormals + sourceMesh->mNumVertices, newMesh->mNormals);
    }
    
    // 复制面数据（必需）
    if (sourceMesh->mFaces && sourceMesh->mNumFaces > 0) {
        newMesh->mFaces = new aiFace[sourceMesh->mNumFaces];
        for (unsigned int i = 0; i < sourceMesh->mNumFaces; ++i) {
            newMesh->mFaces[i].mNumIndices = sourceMesh->mFaces[i].mNumIndices;
            if (sourceMesh->mFaces[i].mIndices && sourceMesh->mFaces[i].mNumIndices > 0) {
                newMesh->mFaces[i].mIndices = new unsigned int[sourceMesh->mFaces[i].mNumIndices];
                
                // 添加边界检查
                for (unsigned int j = 0; j < sourceMesh->mFaces[i].mNumIndices; ++j) {
                    if (sourceMesh->mFaces[i].mIndices[j] < sourceMesh->mNumVertices) {
                        newMesh->mFaces[i].mIndices[j] = sourceMesh->mFaces[i].mIndices[j];
                    } else {
                        // 如果索引超出范围，设置为0
                        newMesh->mFaces[i].mIndices[j] = 0;
                        qDebug() << "copyMesh: Invalid vertex index" << sourceMesh->mFaces[i].mIndices[j] << "in face" << i << "index" << j;
                    }
                }
            } else {
                newMesh->mFaces[i].mIndices = nullptr;
            }
        }
    }
    
    // 复制UV坐标（根据用户选项决定复制多少）
    for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
        if (sourceMesh->mTextureCoords[i] && sourceMesh->mNumVertices > 0) {
            newMesh->mTextureCoords[i] = new aiVector3D[sourceMesh->mNumVertices];
            std::copy(sourceMesh->mTextureCoords[i], sourceMesh->mTextureCoords[i] + sourceMesh->mNumVertices, newMesh->mTextureCoords[i]);
            newMesh->mNumUVComponents[i] = sourceMesh->mNumUVComponents[i];
        } else {
            newMesh->mTextureCoords[i] = nullptr;
            newMesh->mNumUVComponents[i] = 0;
        }
    }
    
    // 复制切线空间数据（如果存在且用户没有选择丢弃）
    if (sourceMesh->mTangents && sourceMesh->mNumVertices > 0) {
        newMesh->mTangents = new aiVector3D[sourceMesh->mNumVertices];
        std::copy(sourceMesh->mTangents, sourceMesh->mTangents + sourceMesh->mNumVertices, newMesh->mTangents);
    } else {
        newMesh->mTangents = nullptr;
    }
    
    if (sourceMesh->mBitangents && sourceMesh->mNumVertices > 0) {
        newMesh->mBitangents = new aiVector3D[sourceMesh->mNumVertices];
        std::copy(sourceMesh->mBitangents, sourceMesh->mBitangents + sourceMesh->mNumVertices, newMesh->mBitangents);
    } else {
        newMesh->mBitangents = nullptr;
    }
    
    // 复制颜色数据（如果存在）
    for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
        if (sourceMesh->mColors[i] && sourceMesh->mNumVertices > 0) {
            newMesh->mColors[i] = new aiColor4D[sourceMesh->mNumVertices];
            std::copy(sourceMesh->mColors[i], sourceMesh->mColors[i] + sourceMesh->mNumVertices, newMesh->mColors[i]);
        } else {
            newMesh->mColors[i] = nullptr;
        }
    }
    
    // 复制骨骼数据（如果存在且用户没有选择移除骨骼）
    if (sourceMesh->mBones && sourceMesh->mNumBones > 0) {
        try {
            newMesh->mBones = new aiBone*[sourceMesh->mNumBones];
            newMesh->mNumBones = sourceMesh->mNumBones;
            
            for (unsigned int i = 0; i < sourceMesh->mNumBones; ++i) {
                if (sourceMesh->mBones[i]) {
                    newMesh->mBones[i] = new aiBone();
                    newMesh->mBones[i]->mName = sourceMesh->mBones[i]->mName;
                    newMesh->mBones[i]->mOffsetMatrix = sourceMesh->mBones[i]->mOffsetMatrix;
                    newMesh->mBones[i]->mNumWeights = sourceMesh->mBones[i]->mNumWeights;
                    
                    if (sourceMesh->mBones[i]->mWeights && sourceMesh->mBones[i]->mNumWeights > 0) {
                        newMesh->mBones[i]->mWeights = new aiVertexWeight[sourceMesh->mBones[i]->mNumWeights];
                        std::copy(sourceMesh->mBones[i]->mWeights, 
                                 sourceMesh->mBones[i]->mWeights + sourceMesh->mBones[i]->mNumWeights, 
                                 newMesh->mBones[i]->mWeights);
                    } else {
                        newMesh->mBones[i]->mWeights = nullptr;
                    }
                } else {
                    newMesh->mBones[i] = nullptr;
                }
            }
        } catch (const std::exception &e) {
            qDebug() << "Error copying bone data:" << QString::fromStdString(e.what());
            // 如果复制失败，设置为空
            newMesh->mBones = nullptr;
            newMesh->mNumBones = 0;
        } catch (...) {
            qDebug() << "Unknown error copying bone data";
            // 如果复制失败，设置为空
            newMesh->mBones = nullptr;
            newMesh->mNumBones = 0;
        }
    } else {
        newMesh->mBones = nullptr;
        newMesh->mNumBones = 0;
    }
    
    // 复制动画网格数据（如果存在）
    if (sourceMesh->mAnimMeshes && sourceMesh->mNumAnimMeshes > 0) {
        newMesh->mAnimMeshes = new aiAnimMesh*[sourceMesh->mNumAnimMeshes];
        newMesh->mNumAnimMeshes = sourceMesh->mNumAnimMeshes;
        
        for (unsigned int i = 0; i < sourceMesh->mNumAnimMeshes; ++i) {
            if (sourceMesh->mAnimMeshes[i]) {
                newMesh->mAnimMeshes[i] = new aiAnimMesh();
                // 复制动画网格的基本属性
                newMesh->mAnimMeshes[i]->mName = sourceMesh->mAnimMeshes[i]->mName;
                newMesh->mAnimMeshes[i]->mNumVertices = sourceMesh->mAnimMeshes[i]->mNumVertices;
                newMesh->mAnimMeshes[i]->mWeight = sourceMesh->mAnimMeshes[i]->mWeight;
                
                // 复制顶点位置
                if (sourceMesh->mAnimMeshes[i]->mVertices) {
                    newMesh->mAnimMeshes[i]->mVertices = new aiVector3D[sourceMesh->mAnimMeshes[i]->mNumVertices];
                    std::copy(sourceMesh->mAnimMeshes[i]->mVertices, 
                             sourceMesh->mAnimMeshes[i]->mVertices + sourceMesh->mAnimMeshes[i]->mNumVertices, 
                             newMesh->mAnimMeshes[i]->mVertices);
                }
                
                // 复制法线
                if (sourceMesh->mAnimMeshes[i]->mNormals) {
                    newMesh->mAnimMeshes[i]->mNormals = new aiVector3D[sourceMesh->mAnimMeshes[i]->mNumVertices];
                    std::copy(sourceMesh->mAnimMeshes[i]->mNormals, 
                             sourceMesh->mAnimMeshes[i]->mNormals + sourceMesh->mAnimMeshes[i]->mNumVertices, 
                             newMesh->mAnimMeshes[i]->mNormals);
                }
            } else {
                newMesh->mAnimMeshes[i] = nullptr;
            }
        }
    } else {
        newMesh->mAnimMeshes = nullptr;
        newMesh->mNumAnimMeshes = 0;
    }
    
    return newMesh;
}

// 新增：纹理嵌入相关函数实现

void ModelOptimizer::embedTexturesInScene(aiScene *scene, const QString &modelPath)
{
    if (!scene || !scene->mMaterials) {
        qDebug() << "No materials to process for texture embedding";
        return;
    }
    
    QFileInfo modelFileInfo(modelPath);
    QString modelDir = modelFileInfo.absolutePath();
    
    qDebug() << "Starting texture embedding for" << scene->mNumMaterials << "materials";
    qDebug() << "Model directory:" << modelDir;
    
    // 统计嵌入的纹理数量
    int embeddedCount = 0;
    
    // 遍历所有材质
    for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
        aiMaterial *material = scene->mMaterials[i];
        if (!material) continue;
        
        // 检查各种纹理类型
        const aiTextureType textureTypes[] = {
            aiTextureType_DIFFUSE,
            aiTextureType_SPECULAR,
            aiTextureType_AMBIENT,
            aiTextureType_EMISSIVE,
            aiTextureType_HEIGHT,
            aiTextureType_NORMALS,
            aiTextureType_SHININESS,
            aiTextureType_OPACITY,
            aiTextureType_DISPLACEMENT,
            aiTextureType_LIGHTMAP,
            aiTextureType_REFLECTION,
            aiTextureType_UNKNOWN
        };
        
        bool materialProcessed = false;
        
        for (aiTextureType textureType : textureTypes) {
            if (materialProcessed) break;
            
            unsigned int textureCount = material->GetTextureCount(textureType);
            for (unsigned int j = 0; j < textureCount; ++j) {
                aiString texturePath;
                aiTextureMapping mapping;
                unsigned int uvIndex;
                float blend;
                aiTextureOp op;
                aiTextureMapMode mapMode[3];
                
                if (material->GetTexture(textureType, j, &texturePath, &mapping, &uvIndex, &blend, &op, mapMode) == AI_SUCCESS) {
                    QString textureFile = QString::fromUtf8(texturePath.C_Str());
                    
                    // 跳过已经嵌入的纹理（以*开头的）
                    if (textureFile.startsWith("*")) {
                        qDebug() << "Texture already embedded:" << textureFile;
                        continue;
                    }
                    
                    qDebug() << "Processing texture:" << textureFile << "for material" << i << "type" << (int)textureType;
                    
                    // 查找纹理文件
                    QString fullTexturePath = findTextureFile(textureFile, modelDir);
                    if (fullTexturePath.isEmpty()) {
                        qDebug() << "Could not find texture file:" << textureFile;
                        continue;
                    }
                    
                    // 嵌入纹理
                    aiTexture *embeddedTexture = nullptr;
                    if (loadAndEmbedTexture(fullTexturePath, &embeddedTexture)) {
                        // 将嵌入的纹理添加到场景中
                        if (!scene->mTextures) {
                            scene->mTextures = new aiTexture*[1];
                            scene->mNumTextures = 1;
                        } else {
                            // 扩展纹理数组
                            aiTexture **newTextures = new aiTexture*[scene->mNumTextures + 1];
                            for (unsigned int k = 0; k < scene->mNumTextures; ++k) {
                                newTextures[k] = scene->mTextures[k];
                            }
                            delete[] scene->mTextures;
                            scene->mTextures = newTextures;
                            scene->mTextures[scene->mNumTextures] = embeddedTexture;
                            scene->mNumTextures++;
                        }
                        
                        // 更新材质中的纹理路径为嵌入索引
                        QString embeddedPath = QString("*%1").arg(scene->mNumTextures - 1);
                        aiString newPath(embeddedPath.toStdString());
                        material->RemoveProperty(AI_MATKEY_TEXTURE(textureType, j));
                        material->AddProperty(&newPath, AI_MATKEY_TEXTURE(textureType, j));
                        
                        embeddedCount++;
                        materialProcessed = true;
                        qDebug() << "Successfully embedded texture:" << fullTexturePath << "as" << embeddedPath;
                        break;
                    } else {
                        qDebug() << "Failed to embed texture:" << fullTexturePath;
                    }
                }
            }
        }
    }
    
    qDebug() << "Texture embedding completed. Embedded" << embeddedCount << "textures.";
}

void ModelOptimizer::embedTextureInMaterial(aiMaterial *material, const QString &texturePath, const QString &modelDir)
{
    if (!material) return;
    
    // 这个函数是辅助函数，主要逻辑在embedTexturesInScene中实现
    qDebug() << "Embedding texture in material:" << texturePath;
}

bool ModelOptimizer::loadAndEmbedTexture(const QString &texturePath, aiTexture **embeddedTexture)
{
    if (!embeddedTexture) return false;
    
    QFile textureFile(texturePath);
    if (!textureFile.exists()) {
        qDebug() << "Texture file does not exist:" << texturePath;
        return false;
    }
    
    if (!textureFile.open(QIODevice::ReadOnly)) {
        qDebug() << "Cannot open texture file:" << texturePath;
        return false;
    }
    
    QByteArray textureData = textureFile.readAll();
    textureFile.close();
    
    if (textureData.isEmpty()) {
        qDebug() << "Texture file is empty:" << texturePath;
        return false;
    }
    
    // 创建嵌入纹理对象
    *embeddedTexture = new aiTexture();
    
    // 设置纹理属性
    (*embeddedTexture)->mWidth = textureData.size();  // 压缩纹理的大小
    (*embeddedTexture)->mHeight = 0;  // 0表示压缩纹理
    
    // 复制纹理数据
    (*embeddedTexture)->pcData = new aiTexel[textureData.size()];
    memcpy((*embeddedTexture)->pcData, textureData.constData(), textureData.size());
    
    // 设置格式提示（基于文件扩展名）
    QFileInfo fileInfo(texturePath);
    QString extension = fileInfo.suffix().toLower();
    
    if (extension == "png") {
        strcpy((*embeddedTexture)->achFormatHint, "png");
    } else if (extension == "jpg" || extension == "jpeg") {
        strcpy((*embeddedTexture)->achFormatHint, "jpg");
    } else if (extension == "tga") {
        strcpy((*embeddedTexture)->achFormatHint, "tga");
    } else if (extension == "bmp") {
        strcpy((*embeddedTexture)->achFormatHint, "bmp");
    } else {
        strcpy((*embeddedTexture)->achFormatHint, "raw");
    }
    
    qDebug() << "Successfully loaded texture:" << texturePath << "size:" << textureData.size() << "format:" << (*embeddedTexture)->achFormatHint;
    return true;
}

QString ModelOptimizer::findTextureFile(const QString &texturePath, const QString &modelDir)
{
    // 首先检查绝对路径
    if (QFile::exists(texturePath)) {
        return texturePath;
    }
    
    // 检查相对于模型目录的路径
    QString relativePath = modelDir + "/" + texturePath;
    if (QFile::exists(relativePath)) {
        return relativePath;
    }
    
    // 检查纹理目录
    QString textureDir = modelDir + "/textures/";
    QString textureDirPath = textureDir + texturePath;
    if (QFile::exists(textureDirPath)) {
        return textureDirPath;
    }
    
    // 检查材质目录
    QString materialDir = modelDir + "/materials/";
    QString materialDirPath = materialDir + texturePath;
    if (QFile::exists(materialDirPath)) {
        return materialDirPath;
    }
    
    // 尝试从文件名中提取路径
    QFileInfo fileInfo(texturePath);
    QString fileName = fileInfo.fileName();
    
    // 在模型目录中搜索文件名
    QDir modelDirectory(modelDir);
    QStringList filters;
    filters << fileName;
    QStringList foundFiles = modelDirectory.entryList(filters, QDir::Files, QDir::Name);
    
    if (!foundFiles.isEmpty()) {
        return modelDir + "/" + foundFiles.first();
    }
    
    // 递归搜索子目录
    QStringList subdirs = modelDirectory.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
    for (const QString &subdir : subdirs) {
        QString subdirPath = modelDir + "/" + subdir;
        QDir subDirectory(subdirPath);
        QStringList foundInSubdir = subDirectory.entryList(filters, QDir::Files, QDir::Name);
        if (!foundInSubdir.isEmpty()) {
            return subdirPath + "/" + foundInSubdir.first();
        }
    }
    
    qDebug() << "Could not find texture file:" << texturePath << "in directory:" << modelDir;
    return QString();
}

// 新增：验证用户选择的优化选项
bool ModelOptimizer::validateOptimizationOptions(const OptimizationOptions &options, QString &warningMessage)
{
    warningMessage.clear();
    bool isValid = true;
    
    // 检查顶点减少比例
    if (options.vertexReduction < 0.0f || options.vertexReduction > 0.95f) {
        warningMessage += "顶点减少比例应在0-95%之间，当前值: " + QString::number(options.vertexReduction * 100, 'f', 1) + "%\n";
        isValid = false;
    }
    
    // 检查容差值
    if (options.normalTolerance < 0.0f || options.normalTolerance > 1.0f) {
        warningMessage += "法线容差应在0-1之间，当前值: " + QString::number(options.normalTolerance, 'f', 3) + "\n";
        isValid = false;
    }
    
    if (options.uvTolerance < 0.0f || options.uvTolerance > 1.0f) {
        warningMessage += "UV容差应在0-1之间，当前值: " + QString::number(options.uvTolerance, 'f', 3) + "\n";
        isValid = false;
    }
    
    // 检查冲突的选项
    if (options.generateNormals && options.dropNormals) {
        warningMessage += "同时选择生成法线和丢弃法线是冲突的\n";
        isValid = false;
    }
    
    if (options.generateSmoothNormals && options.dropNormals) {
        warningMessage += "同时选择生成平滑法线和丢弃法线是冲突的\n";
        isValid = false;
    }
    
    if (options.calculateTangentSpace && options.dropNormals) {
        warningMessage += "计算切线空间需要法线，但选择了丢弃法线\n";
        isValid = false;
    }
    
    // 检查是否有任何优化选项被选中
    bool hasAnyOptimization = options.removeUnusedVertices ||
                             options.joinIdenticalVertices ||
                             options.vertexReduction > 0.0f ||
                             options.triangulate ||
                             options.generateNormals ||
                             options.generateSmoothNormals ||
                             options.calculateTangentSpace ||
                             options.removeRedundantMaterials ||
                             options.embedTextures ||
                             options.optimizeMeshes ||
                             options.optimizeGraph;
    
    if (!hasAnyOptimization) {
        warningMessage += "没有选择任何优化选项，模型将不会被优化\n";
        // 这不是错误，只是警告
    }
    
    // 检查纹理嵌入相关的选项
    if (options.embedTextures) {
        if (options.vertexReduction > 0.8f) {
            warningMessage += "高顶点减少比例可能影响纹理质量\n";
        }
    }
    
    return isValid;
} 